// 羊了个羊 - 100%按照Vue版本实现
class CardItem {
  static x = 40;  // 卡片宽度，更容易点击
  static y = 40;  // 卡片高度，更容易点击
  static colorType = {
    1: { background: "#FFB7DD" },
    2: { background: "#FFCCCC" },
    3: { background: "#FFC8B4" },
    4: { background: "#FFDDAA" },
    5: { background: "#FFEE99" },
    6: { background: "#FFFFBB" },
    7: { background: "#EEFFBB" },
    8: { background: "#CCFF99" },
    9: { background: "#99FF99" },
    10: { background: "#BBFFEE" },
    11: { background: "#AAFFEE" },
    12: { background: "#99FFFF" },
    13: { background: "#CCEEFF" },
    14: { background: "#CCDDFF" },
  };
  static contentType = {
    1: "🥕",
    2: "✂️",
    3: "🥦",
    4: "🥛",
    5: "🌊",
    6: "🧤",
    7: "🧵",
    8: "🌱",
    9: "🔨",
    10: "🌽",
    11: "🌾",
    12: "🐑",
    13: "🪵",
    14: "🔥",
  };

  constructor({ x, y, z, key }) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.key = key;
    const offset = z * 0;
    this.val = key;
    this.style = {
      top: y * CardItem.y + offset + "rpx",
      left: x * CardItem.x + offset + "rpx",
      width: CardItem.x * 2 - 2 + "rpx",
      height: CardItem.y * 2 - 8 + "rpx",
    };
  }

  setValue(val) {
    this.val = val;
    this.content = CardItem.contentType[val];
    Object.assign(this.style, CardItem.colorType[val]);
  }
}

Page({
  data: {
    option: {
      x: 10,           // 横向卡片最大平铺排数
      y: 10,           // 纵向卡片最大平铺排数
      z: 8,            // 卡片最大堆叠层数
      cardRandom: 0.2, // 卡片密度
      maxCardType: 10, // 最大卡片种类
    },
    step: 1,           // 游戏步骤：0=设置，1=游戏中，2=结束（直接开始游戏）
    result: false,     // 游戏结果
    cardMap: [],       // 卡片地图
    cardItemList: [],  // 游戏区卡片列表
    penddingList: [],  // 收集栏卡片列表
    clearList: [],     // 已消除卡片列表
    saveList: [],      // 保存的卡片列表
    calcValueList: [], // 卡片数量统计
    maxWidth: 0,       // 地图最大宽度
    maxHeight: 0,      // 地图最大高度
    tools: {
      save: true,      // 取出3个卡片
      rand: true       // 随机洗牌
    },
    timer: 0,          // 定时器

    // 音乐控制
    musicPlaying: false,
    backgroundMusic: null,
    currentMusicIndex: 0,
    musicList: [
      'http://music.163.com/song/media/outer/url?id=415793857.mp3',
      'http://music.163.com/song/media/outer/url?id=30854122.mp3',
      'http://music.163.com/song/media/outer/url?id=2101789305.mp3'
    ],

    // 计算属性
    cardWrapStyle: "",
    leftOffset: 0
  },

  onLoad() {
    this.initMusic();
    this.initGame();
    // 自动播放背景音乐
    if (!this.data.musicPlaying) {
      this.startMusic();
    }
  },

  // 计算卡片容器样式
  updateCardWrapStyle() {
    const style = `width: ${(this.data.maxWidth + 2) * CardItem.x}rpx; height: ${(this.data.maxHeight + 1) * CardItem.y}rpx;`;
    const wrapWidth = (this.data.maxWidth + 2) * CardItem.x;
    const leftOffset = (wrapWidth - 7 * CardItem.x * 2) / 2;

    this.setData({
      cardWrapStyle: style,
      leftOffset: leftOffset
    });
  },

  // 开始游戏（从设置页面点击开始）
  startGame() {
    this.initGame();
    // 开始游戏时自动播放音乐
    if (!this.data.musicPlaying) {
      this.startMusic();
    }
  },

  // 设置游戏
  setGame() {
    this.setData({ step: 0 });
  },

  // 重新开始
  rePlay() {
    this.initGame();
  },

  // 初始化游戏
  initGame() {
    this.setData({
      step: 1,
      penddingList: [],
      clearList: [],
      saveList: [],
      tools: { save: true, rand: true }
    });

    this.getMap(this.data.option);
    this.setCardValue({ maxCardType: Number(this.data.option.maxCardType) });
    this.calcCover();
  },

  // 生成地图 - 完全按照Vue版本
  getMap({ x, y, z, cardRandom } = {}) {
    this.data.maxWidth = (x - 1) * 2;
    this.data.maxHeight = (y - 1) * 2 + 1;
    const cardMap = new Array(z);
    const cardItemList = [];
    let key = 0;

    // 地图初始化
    for (let k = 0; k < z; k++) {
      cardMap[k] = new Array(this.data.maxHeight);
      for (let i = 0; i <= this.data.maxHeight; i++) {
        cardMap[k][i] = new Array(this.data.maxWidth).fill(0);
      }
    }

    for (let k = 0; k < z; k++) {
      const shrink = Math.floor((z - k) / 3);
      // 行
      for (let i = shrink; i < this.data.maxHeight - shrink; i++) {
        // 列，对称设置
        const mid = Math.ceil((this.data.maxWidth - shrink) / 2);
        for (let j = shrink; j <= mid; j++) {
          let canSetCard = true;
          if (j > 0 && cardMap[k][i][j - 1]) {
            // 左边不能有牌
            canSetCard = false;
          } else if (i > 0 && cardMap[k][i - 1][j]) {
            // 上边不能有牌
            canSetCard = false;
          } else if (i > 0 && j > 0 && cardMap[k][i - 1][j - 1]) {
            // 左上不能有牌
            canSetCard = false;
          } else if (i > 0 && cardMap[k][i - 1][j + 1]) {
            // 右上不能有牌
            canSetCard = false;
          } else if (k > 0 && cardMap[k - 1][i][j]) {
            // 正底不能有牌
            canSetCard = false;
          } else if (Math.random() >= cardRandom) {
            canSetCard = false;
          }

          if (canSetCard) {
            key++;
            const cardItem = new CardItem({ x: j, y: i, z: k, key });
            cardMap[k][i][j] = cardItem;
            cardItemList.push(cardItem);
            // 对称放置
            if (j < mid) {
              key++;
              const cardItem2 = new CardItem({
                x: this.data.maxWidth - j,
                y: i,
                z: k,
                key,
              });
              cardMap[k][i][this.data.maxWidth - j] = cardItem2;
              cardItemList.push(cardItem2);
            }
          }
        }
      }
    }

    cardItemList.reverse();
    for (let i = 1; i <= key % 3; i++) {
      const clearItem = cardItemList.pop();
      cardMap[clearItem.z][clearItem.y][clearItem.x] = 0;
    }
    cardItemList.reverse();

    this.setData({
      cardMap,
      cardItemList,
      maxWidth: this.data.maxWidth,
      maxHeight: this.data.maxHeight
    });

    this.updateCardWrapStyle();
  },

  // 设置卡片值 - 完全按照Vue版本
  setCardValue({ maxCardType } = {}) {
    // 卡片种类
    const valStack = new Array(maxCardType);
    this.data.calcValueList = new Array(maxCardType + 1).fill(0);

    // 给卡片设置值
    this.data.cardItemList.forEach((item) => {
      const value = Math.ceil(Math.random() * maxCardType);
      if (valStack[value]) {
        valStack[value].push(item);
        if (valStack[value].length === 3) {
          valStack[value].forEach((item) => {
            item.setValue(value);
          });
          valStack[value] = null;
        }
      } else {
        valStack[value] = [item];
      }
    });

    let count = 2;
    // 处理剩余卡片
    valStack.forEach((list) => {
      list &&
        list.forEach((item) => {
          count++;
          item.setValue(Math.floor(count / 3));
        });
    });

    this.setData({
      cardItemList: this.data.cardItemList,
      calcValueList: this.data.calcValueList
    });
  },

  // 计算遮挡关系 - 完全按照Vue版本
  calcCover() {
    // 构建一个遮挡 map
    const coverMap = new Array(this.data.maxHeight);
    for (let i = 0; i <= this.data.maxHeight; i++) {
      coverMap[i] = new Array(this.data.maxWidth).fill(false);
    }

    // 从后往前，后面的层数高
    for (let i = this.data.cardItemList.length - 1; i >= 0; i--) {
      const item = this.data.cardItemList[i];
      const { x, y } = item;
      if (coverMap[y][x]) {
        item.cover = true;
      } else if (coverMap[y][x + 1]) {
        item.cover = true;
      } else if (coverMap[y + 1][x]) {
        item.cover = true;
      } else if (coverMap[y + 1][x + 1]) {
        item.cover = true;
      } else {
        item.cover = false;
      }
      coverMap[y][x] = true;
      coverMap[y + 1][x] = true;
      coverMap[y][x + 1] = true;
      coverMap[y + 1][x + 1] = true;
    }

    this.setData({ cardItemList: this.data.cardItemList });
  },

  // 点击卡片 - 完全按照Vue版本
  clickCard(e) {
    const { item } = e.currentTarget.dataset;

    // 检查卡片是否被遮挡，如果被遮挡则不能点击
    if (item.cover) {
      return;
    }

    clearTimeout(this.data.timer);
    this.removeThree();

    const penddingList = [...this.data.penddingList, item];
    const cardItemList = this.data.cardItemList.filter(c => c.key !== item.key);
    const calcValueList = [...this.data.calcValueList];

    this.setData({
      penddingList,
      cardItemList,
      calcValueList
    });

    this.calcCover();
    calcValueList[item.val]++;

    setTimeout(() => {
      const updatedPenddingList = penddingList.map((pItem, index) => {
        const updatedItem = { ...pItem };
        updatedItem.style = { ...pItem.style };
        updatedItem.style.top = "50%"; // 居中显示在收集栏
        updatedItem.style.left = 30 + index * (CardItem.x * 2 + 15) + "rpx"; // 更大间距
        updatedItem.style.zIndex = 9999;
        return updatedItem;
      });

      this.setData({
        penddingList: updatedPenddingList,
        calcValueList
      });
    }, 100);

    const timer = setTimeout(() => {
      this.removeThree();
    }, 500);

    this.setData({ timer });
  },

  // 移除三个相同卡片 - 修改为直接消失
  removeThree() {
    const penddingList = [...this.data.penddingList];
    const calcValueList = [...this.data.calcValueList];

    penddingList.some((item) => {
      if (calcValueList[item.val] === 3) {
        // 直接从收集栏移除三个相同的卡片，不需要移动到别处
        const filteredPenddingList = penddingList.filter((newItem) => {
          return newItem.val !== item.val;
        });

        // 重新排列剩余卡片的位置
        const updatedPenddingList = filteredPenddingList.map((item, index) => {
          const newItem = { ...item };
          newItem.style = { ...item.style };
          newItem.style.top = "50%";
          newItem.style.left = 30 + index * (CardItem.x * 2 + 15) + "rpx";
          newItem.style.zIndex = 1000;
          return newItem;
        });

        calcValueList[item.val] = 0;

        this.setData({
          penddingList: updatedPenddingList,
          calcValueList
        });

        // 检查游戏是否胜利
        if (this.data.cardItemList.length === 0) {
          this.setData({ step: 2, result: true });
        }

        return true;
      }
      return false;
    });

    // 检查游戏是否失败
    if (penddingList.length >= 7) {
      this.setData({ step: 2, result: false });
    }
  },

  // 随机洗牌 - 完全按照Vue版本
  randCard() {
    if (!this.data.tools.rand) {
      return;
    }

    const tools = { ...this.data.tools };
    tools.rand = false;

    const length = this.data.cardItemList.length;
    const cardItemList = [...this.data.cardItemList];

    cardItemList.forEach((item) => {
      const randNum = Math.floor(length * Math.random());
      const newItem = cardItemList[randNum];
      let temp;

      temp = item.style.left;
      item.style.left = newItem.style.left;
      newItem.style.left = temp;

      temp = item.style.top;
      item.style.top = newItem.style.top;
      newItem.style.top = temp;

      temp = item.x;
      item.x = newItem.x;
      newItem.x = temp;

      temp = item.y;
      item.y = newItem.y;
      newItem.y = temp;

      temp = item.z;
      item.z = newItem.z;
      newItem.z = temp;
    });

    cardItemList.sort((a, b) => a.z - b.z);

    this.setData({
      tools,
      cardItemList
    });

    this.calcCover();
  },

  // 取出3个卡片道具 - 把收集栏前3个卡片放回游戏区
  saveCard() {
    if (!this.data.tools.save) {
      return false;
    }

    // 如果收集栏少于3个卡片，不执行
    if (this.data.penddingList.length < 3) {
      wx.showToast({
        title: '收集栏卡片不足3个',
        icon: 'none',
        duration: 1500
      });
      return false;
    }

    const tools = { ...this.data.tools };
    tools.save = false;

    // 取出前3个卡片
    const cardsToReturn = this.data.penddingList.slice(0, 3);
    const penddingList = this.data.penddingList.slice(3);
    const calcValueList = [...this.data.calcValueList];

    // 减少收集栏中的卡片计数
    cardsToReturn.forEach(card => {
      calcValueList[card.val]--;
    });

    // 把这3个卡片放回游戏区（cardItemList）顶部，z-index 设为最高
    const maxZ = Math.max(...this.data.cardItemList.map(item => item.z), 0);
    const returnedCards = cardsToReturn.map(item => {
      const newItem = { ...item };
      newItem.z = maxZ + 1; // 放到最上层
      newItem.cover = false; // 不被遮挡
      return newItem;
    });

    const cardItemList = [...this.data.cardItemList, ...returnedCards];

    // 重新排列剩余收集栏卡片的位置
    const updatedPenddingList = penddingList.map((item, index) => {
      const newItem = { ...item };
      newItem.style = { ...item.style };
      newItem.style.top = "50%";
      newItem.style.left = 30 + index * (CardItem.x * 2 + 15) + "rpx";
      newItem.style.zIndex = 1000;
      return newItem;
    });

    this.setData({
      tools,
      penddingList: updatedPenddingList,
      cardItemList,
      calcValueList,
      saveList: [] // 清空保存列表
    });

    // 重新计算遮挡关系
    this.calcCover();
  },

  // 滑块变化事件
  onSliderChange(e) {
    const { key } = e.currentTarget.dataset;
    const value = e.detail.value;
    const option = { ...this.data.option };
    option[key] = value;
    this.setData({ option });
  },

  // 初始化音乐
  initMusic() {
    this.data.backgroundMusic = wx.createInnerAudioContext();
    this.data.backgroundMusic.loop = false; // 不自动循环，我们手动控制
    this.data.backgroundMusic.volume = 0.5;

    // 监听音乐播放结束事件
    this.data.backgroundMusic.onEnded(() => {
      this.playNextMusic();
    });

    // 监听音乐播放错误
    this.data.backgroundMusic.onError((err) => {
      console.error('音乐播放错误:', err);
      this.playNextMusic(); // 出错时播放下一首
    });
  },

  // 播放下一首音乐
  playNextMusic() {
    if (!this.data.musicPlaying) return;

    this.data.currentMusicIndex = (this.data.currentMusicIndex + 1) % this.data.musicList.length;
    this.setData({ currentMusicIndex: this.data.currentMusicIndex });

    const nextSrc = this.data.musicList[this.data.currentMusicIndex];
    this.data.backgroundMusic.src = nextSrc;
    this.data.backgroundMusic.play();
  },

  // 开始播放音乐
  startMusic() {
    if (!this.data.backgroundMusic) {
      this.initMusic();
    }

    const currentSrc = this.data.musicList[this.data.currentMusicIndex];
    this.data.backgroundMusic.src = currentSrc;
    this.data.backgroundMusic.play();

    this.setData({ musicPlaying: true });
  },

  // 停止播放音乐
  stopMusic() {
    if (this.data.backgroundMusic) {
      this.data.backgroundMusic.stop();
    }
    this.setData({ musicPlaying: false });
  },

  // 切换音乐播放状态
  toggleMusic() {
    if (this.data.musicPlaying) {
      this.stopMusic();
    } else {
      this.startMusic();
    }
  },

  // 页面卸载时清理音乐
  onUnload() {
    if (this.data.backgroundMusic) {
      this.data.backgroundMusic.destroy();
    }
  }
});